package emulator.shell.commands;

import emulator.EmulatorException;
import emulator.assembler.Assembler;
import emulator.assembler.InstructionList;
import emulator.hardware.nmos6502.FloatHelper;
import emulator.shell.DebugShell;
import emulator.shell.ShellCommand;
import emulator.util.AddressRange;

public class Show implements ShellCommand {

	@Override
	public boolean execute(DebugShell shell, String[] arg)
			throws EmulatorException {
		if (arg.length < 2)
		{
			shell.getOut().println("Missing argument!");
			printHelp(shell);
		}
		else
		{
			if (arg[1].equalsIgnoreCase("state"))
				shell.getCpu().printState(shell.getOut());
			else if (arg[1].equalsIgnoreCase("code"))
			{
				AddressRange range = new AddressRange();
				if (arg.length < 3)
				{
					range.setStart(shell.getCpu().getPC());
					range.setEnd(shell.getCpu().getPC());
				}
				else
				{
					try {
						range = AddressRange.fromString(arg[2]);
					} catch (NumberFormatException e) {
						shell.getOut().println("Illegal argument: "+e.getMessage());
						printHelp(shell);
					}
				}
				Assembler assembler = shell.getAssembler();
				InstructionList instructions;
				if (range.getStart() == range.getEnd())
					instructions = assembler.disassembleLines(shell.getMemoryBlock().getData(), range.getStart(), 10);
				else
					instructions = assembler.disassemble(shell.getMemoryBlock().getData(), range.getStart(), range.getEnd());
				shell.getOut().print(instructions.toString());
			}
			else if (arg[1].equalsIgnoreCase("memory"))
			{
				if (arg.length < 3)
				{
					shell.getOut().println("Missing address!");
					printHelp(shell);
				}
				else
				{
					try {
						AddressRange range = AddressRange.fromString(arg[2]);
						range.printMemory(shell.getBus(), shell.getOut());
					} catch (NumberFormatException e) {
						shell.getOut().println("Illegal argument: "+e.getMessage());
						printHelp(shell);
					}
				}
			}
			else if (arg[1].equalsIgnoreCase("float"))
			{
				if (arg.length < 3)
				{
					shell.getOut().println("Missing address!");
					printHelp(shell);
				}
				else
				{
					try {
						AddressRange range = AddressRange.fromString(arg[2]);
						int[] bytes = new int[6];
						for (int i= 0; i < 6; i++)
							bytes[i] = (int)(shell.getBus().read(i+range.getStart()));
						shell.getOut().println("FLTP: "+FloatHelper.fromFLPT(bytes));
						shell.getOut().println("MFLTP: "+FloatHelper.fromMFLPT(bytes));
					} catch (NumberFormatException e) {
						shell.getOut().println("Illegal argument: "+e.getMessage());
						printHelp(shell);
					}
					
				}
			}
			else
			{
				printHelp(shell);
			}
		}
		return false;
	}

	@Override
	public void printHelp(DebugShell shell) {
		shell.getOut().println("command syntax:");
		shell.getOut().println("show state           - show cpu state");
		shell.getOut().println("show memory <address>[:<address2>]");
		shell.getOut().println("                     - show memory contents at <address> (range)");
		shell.getOut().println("show code <address>[:<address2>]");
		shell.getOut().println("                     - show code at <address> (range)");
		shell.getOut().println("show code            - show code at PC");
		shell.getOut().println("show float <address> - show float variable at <address>");
	}

}
